package applet;

import java.applet.Applet;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.HashMap;

//import netscape.javascript.JSObject;
import server.ServerPacket;

public class server_connector_test {
	
	private static final int SERVER_SOCKET = 12345;//remote server
	
	private static final String SERVER = "localhost";//could be localhost for testing

	private static final int BUFFER_SIZE = 5000;
	
	DatagramSocket dsock;
	
	InetSocketAddress server_socket;
	
	public server_connector_test() {
		System.out.println("constructor accessed");
		try {
			dsock = new DatagramSocket();
			
//			this.server_socket = new InetSocketAddress(
//								InetAddress.getByName(SERVER),
//								SERVER_SOCKET);
			this.server_socket = 
					new InetSocketAddress(	InetAddress.getByName(SERVER),//change this
											SERVER_SOCKET);
			System.out.println("\nServer address is:" + server_socket.toString() + "\n");
		} catch (SocketException | UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
			
	}
	
	public Boolean register(String user_id, String password) {
		//form registration packet
		ServerPacket pkt = 
				new ServerPacket(ServerPacket.RequestType.Register, 
									user_id, password, null);
		
		//send to server
		byte[] temp = ServerPacket.serialize(pkt);
		try {
			DatagramPacket dp = 
						new DatagramPacket(temp, temp.length, server_socket);
			dsock.send(dp);
			
			//wait for timeout and return
			dsock.setSoTimeout(1000);
			byte[] buf = new byte[BUFFER_SIZE];
			DatagramPacket new_dp = new DatagramPacket(buf, buf.length);
			dsock.receive(new_dp);
			//??
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	public Boolean login(String user_id, String password) {
		//form registration packet
		//JSObject window = JSObject.getWindow(this);
		//window.setMember("debug_msg", "Calling Login!!!");
		//window.eval("debugMsg()");
		InetSocketAddress p2p_sock = null;
				try {
					p2p_sock =
							new InetSocketAddress (InetAddress.getLocalHost(),
									P2PConnector.P2PConnector.PORT);
				} catch (UnknownHostException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				InetSocketAddress[] addr_array = new InetSocketAddress[1];
				addr_array[0] = p2p_sock;
				ServerPacket pkt = 
						new ServerPacket(ServerPacket.RequestType.Login, 
											user_id, password, addr_array);
				
				//send to server
				byte[] temp = ServerPacket.serialize(pkt);
				try {
					DatagramPacket dp = 
								new DatagramPacket(temp, temp.length, server_socket);
					dsock.send(dp);
					
					//wait for timeout and return
					//dsock.setSoTimeout(1000);
					byte[] buf = new byte[BUFFER_SIZE];
					DatagramPacket new_dp = new DatagramPacket(buf, buf.length);
					dsock.receive(new_dp);
					
					temp = new_dp.getData();
					//System.out.println(temp.toString());
					ServerPacket ret_pkt = ServerPacket.deserialize(temp);
					//System.out.println(pkt.getData());
					if(ret_pkt.getRequestType() == ServerPacket.RequestType.Acknowledgement)
						return true;
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return false;
				}
				return false;
		
	}
	
	public HashMap<String, InetSocketAddress> getUsers(String user_id) {
		//form registration packet
				ServerPacket pkt = 
						new ServerPacket(ServerPacket.RequestType.GetUsers, 
											user_id);
				
				//send to server
				byte[] temp = ServerPacket.serialize(pkt);
				HashMap<String, InetSocketAddress> map = null;
				try {
					DatagramPacket dp = 
								new DatagramPacket(temp, temp.length, server_socket);
					dsock.send(dp);
					
					//wait for timeout and return
					dsock.setSoTimeout(1000);
					
					byte[] buf = new byte[BUFFER_SIZE];
					DatagramPacket new_dp = new DatagramPacket(buf, buf.length);
					dsock.receive(new_dp);
					
					temp = new_dp.getData();
					
					//extract data and add to map
					map = new HashMap<String, InetSocketAddress>();
					
					pkt = ServerPacket.deserialize(temp);
					
					byte[][] user_data = pkt.getUserData();
					
					InetSocketAddress[] address_list = pkt.getAddr();
					
					for(int i = 0; i < user_data.length; i++) {
						map.put(new String(user_data[i]), address_list[i]);
					}
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return map;
		
	}
	
	public Boolean disconnect(String user_id) {
		//form registration packet
				ServerPacket pkt = 
						new ServerPacket(ServerPacket.RequestType.Disconnect, 
											user_id);
				
				//send to server
				byte[] temp = ServerPacket.serialize(pkt);
				try {
					DatagramPacket dp = 
								new DatagramPacket(temp, temp.length, server_socket);
					dsock.send(dp);
					
					//wait for timeout and return
					dsock.setSoTimeout(1000);
					dsock.receive(dp);
					//??
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					return false;
				}
				return true;
				
	}
	
}
